﻿using System;
using System.Runtime.InteropServices;
using System.Text;


namespace IupNET
{


  public static class Iupc
  {

    const string module = "iupnet-c.dll";

    [DllImport(module)]
    public extern static IntPtr FileDlg();

    [DllImport(module)]
    public extern static IntPtr MessageDlg();

    [DllImport(module)]
    public extern static IntPtr ColorDlg();

    [DllImport(module)]
    public extern static IntPtr FontDlg();


    [DllImport(module)]
    public extern static int GetFile(StringBuilder sb);
    public static int GetFile(ref string str)
    {
      StringBuilder sb = new StringBuilder(str, 500);
      int res = GetFile(sb);
      str = sb.ToString();
      return res;
    }

    [DllImport(module)]
    public extern static void Message(string title, string msg);

    [DllImport(module)]
    public extern static int Alarm(string title, string msg, string b1, string b2, string b3);

    [DllImport(module)]
    public extern static int ListDialog(int type, string title, int size, string[] list, int op, int max_col, int max_lin, int[] mark);

    [DllImport(module)]
    public extern static int GetText(string title, StringBuilder text);
    public static int GetText(string title, ref string text)
    {
      StringBuilder sb = new StringBuilder(text, 10000); //TODO: should we care for more than 10k text?
      int res = GetText(title, sb);
      text = sb.ToString();
      return res;
    }

    [DllImport(module)]
    public extern static int GetColor(int x, int y, ref byte r, ref byte g, ref byte b);

    //TODO: try if/how GetParamv works...

    [DllImport(module)]
    public extern static int GetParamv(string title, IntPtr action, IntPtr userdata, string format, int param_count, int param_extra, [Out]IntPtr[] param_data);

    [DllImport(module)]
    public extern static int Open(IntPtr argc, IntPtr argv);

    [DllImport(module)]
    public extern static void Close();

    //TODO: imagelib open
    [DllImport(module)]
    public extern static int MainLoop();

    [DllImport(module)]
    public extern static int LoopStep();

    [DllImport(module)]
    public extern static int MainLoopLevel();

    [DllImport(module)]
    public extern static void Flush();

    [DllImport(module)]
    public extern static void ExitLoop();

    [DllImport(module)]
    public extern static void Update(IntPtr ih);

    [DllImport(module)]
    public extern static void UpdateChildren(IntPtr ih);

    [DllImport(module)]
    public extern static void Redraw(IntPtr ih, int children);

    [DllImport(module)]
    public extern static void Refresh(IntPtr ih);

    [DllImport(module,EntryPoint="MapFont")]
    private extern static IntPtr MapFontPtr(string iupfont);
    public static string MapFont(string iupfont)
    {
      return PtrToString(MapFontPtr(iupfont));
    }

    [DllImport(module,EntryPoint="UnMapFont")]
    private extern static IntPtr UnMapFontPtr(string driverfont);
    public static string UnMapFont(string driverfont)
    {
      return PtrToString(UnMapFontPtr(driverfont));
    }

    [DllImport(module)]
    public extern static int Help(string url);

    [DllImport(module,EntryPoint="Load")]
    private extern static IntPtr LoadPtr(string filename);
    public static string Load(string filename)
    {
      return PtrToString(LoadPtr(filename));
    }

    [DllImport(module,EntryPoint="Version")]
    private extern static IntPtr VersionPtr();
    public static string Version()
    {
      return PtrToString(VersionPtr());
    }


    [DllImport(module,EntryPoint="VersionDate")]
    private extern static IntPtr VersionDatePtr();
    public static string VersionDate()
    {
      return PtrToString(VersionDatePtr());
    }


    [DllImport(module)]
    public extern static int VersionNumber();

    [DllImport(module)]
    public extern static void SetLanguage(string lng);

    [DllImport(module, EntryPoint = "GetLanguage")]
    internal extern static IntPtr GetLanguagePtr();
    public static string GetLanguage()
    {
      return PtrToString(GetLanguagePtr());
    }



    [DllImport(module)]
    public extern static void Destroy(IntPtr ih);

    [DllImport(module)]
    public extern static void Detach(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr Append(IntPtr ih, IntPtr child);

    [DllImport(module)]
    public extern static IntPtr Insert(IntPtr ih, IntPtr ref_child, IntPtr child);

    [DllImport(module)]
    public extern static IntPtr GetChild(IntPtr ih, int pos);

    [DllImport(module)]
    public extern static int GetChildPos(IntPtr ih, IntPtr child);

    [DllImport(module)]
    public extern static int GetChildCount(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetNextChild(IntPtr ih, IntPtr child);

    [DllImport(module)]
    public extern static IntPtr GetBrother(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetParent(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetDialog(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetDialogChild(IntPtr ih, string name);

    [DllImport(module)]
    public extern static int Reparent(IntPtr ih, IntPtr new_parent);

    [DllImport(module)]
    public extern static int Popup(IntPtr ih, int x, int y);

    [DllImport(module)]
    public extern static int Show(IntPtr ih);

    [DllImport(module)]
    public extern static int ShowXY(IntPtr ih, int x, int y);

    [DllImport(module)]
    public extern static int Hide(IntPtr ih);

    [DllImport(module)]
    public extern static int Map(IntPtr ih);

    [DllImport(module)]
    public extern static void Unmap(IntPtr ih);

    [DllImport(module)]
    public extern static void StoreAttribute(IntPtr ih, string name, string value);

    [DllImport(module, EntryPoint = "SetAttribute")]
    public extern static void SetAttributePtr(IntPtr ih, string name, IntPtr value);

    [DllImport(module)]
    public extern static IntPtr SetAttributes(IntPtr ih, string str);

    [DllImport(module, EntryPoint = "GetAttribute")]
    public extern static IntPtr GetAttributePtr(IntPtr ih, string name);
    public static string GetAttribute(IntPtr ih, string name)
    {
      return PtrToString(GetAttributePtr(ih, name));
    }




    [DllImport(module, EntryPoint = "GetAttributes")]
    private extern static IntPtr GetAttributesPtr(IntPtr ih);
    public static string GetAttributes(IntPtr ih)
    {
      IntPtr p = GetAttributesPtr(ih);
      return PtrToString(p);
    }


    [DllImport(module)]
    public extern static int GetInt(IntPtr ih, string name);

    [DllImport(module)]
    public extern static int GetInt2(IntPtr ih, string name);

    [DllImport(module)]
    public extern static int GetIntInt(IntPtr ih, string name, out int i1, out int i2); 

    [DllImport(module)]
    public extern static float GetFloat(IntPtr ih, string name);

    [DllImport(module)]
    public extern static int GetAllAttributes(IntPtr ih, [Out]IntPtr[] names, int n);

    [DllImport(module)]
    public extern static void StoreGlobal(string name, string value);

    [DllImport(module, EntryPoint = "GetGlobal")]
    private extern static IntPtr GetGlobalPtr(string name);
    public static string GetGlobal(string name)
    {
      return PtrToString(GetGlobalPtr(name));
    }

    [DllImport(module)]
    public extern static IntPtr SetFocus(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetFocus();

    [DllImport(module)]
    public extern static IntPtr PreviousField(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr NextField(IntPtr ih);

    [DllImport(module)]
    public extern static IntPtr GetCallback(IntPtr ih, string name);

    [DllImport(module)]
    public extern static IntPtr SetCallback(IntPtr ih, string name, IntPtr func);

    [DllImport(module)]
    public extern static IntPtr GetFunction(string name);

    [DllImport(module)]
    public extern static IntPtr SetFunction(string name, IntPtr func);

    [DllImport(module,EntryPoint="GetActionName")]
    private extern static IntPtr GetActionNamePtr();
    public static string GetActionName()
    {
      return PtrToString(GetActionNamePtr());
    }


    [DllImport(module)]
    public extern static IntPtr GetHandle(string name);

    [DllImport(module)]
    public extern static IntPtr SetHandle(string name, IntPtr ih);

    [DllImport(module)]
    public extern static int GetAllNames([Out]string[] names, int n);

    [DllImport(module)]
    public extern static int GetAllDialogs([Out]string[] names, int n);

    [DllImport(module,EntryPoint="GetName")]
    private extern static IntPtr GetNamePtr(IntPtr ih);
    public static string GetName(IntPtr ih)
    {
      return PtrToString(GetNamePtr(ih));
    }

    [DllImport(module)]
    public extern static void SetAttributeHandle(IntPtr ih, string name, IntPtr ih_named);

    [DllImport(module,EntryPoint="GetClassName")]
    public extern static IntPtr GetClassNamePtr(IntPtr ih);
    public static string GetClassName(IntPtr ih)
    {
      return PtrToString(GetClassNamePtr(ih));
    }

    [DllImport(module,EntryPoint="GetClassType")]
    private extern static IntPtr GetClassTypePtr(IntPtr ih);
    public static string GetClassType(IntPtr ih)
    {
      return PtrToString(GetClassTypePtr(ih));
    }


    [DllImport(module)]
    public extern static int GetClassAttributes(string classname, [Out]string[] names, int n);

    [DllImport(module)]
    public extern static void SaveClassAttribute(IntPtr ih);

    [DllImport(module)]
    public extern static void SetClassDefaultAttribute(string classname, string name, string value);

    [DllImport(module)]
    public extern static IntPtr Create(string classname);

    [DllImport(module)]
    public extern static IntPtr Createv(string classname, params IntPtr[] parms);

    [DllImport(module)]
    public extern static IntPtr Fill();

    [DllImport(module)]
    public extern static IntPtr Radio(IntPtr child);

    [DllImport(module)]
    public extern static IntPtr Vboxv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Zboxv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Hboxv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Normalizerv(params IntPtr[] ih_list);

    [DllImport(module)]
    public extern static IntPtr Cboxv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Sbox(IntPtr child);

    [DllImport(module)]
    public extern static IntPtr Frame(IntPtr child);

    [DllImport(module)]
    public extern static IntPtr Image(int width, int height, byte[] pixmap);

    [DllImport(module)]
    public extern static IntPtr ImageRGB(int width, int height, byte[] pixmap);

    [DllImport(module)]
    public extern static IntPtr ImageRGBA(int width, int height, byte[] pixmap);

    [DllImport(module)]
    public extern static IntPtr Item(string title, string action);

    [DllImport(module)]
    public extern static IntPtr Submenu(string title, IntPtr child);

    [DllImport(module)]
    public extern static IntPtr Separator();

    [DllImport(module)]
    public extern static IntPtr Menuv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Button(string title, string action);

    [DllImport(module)]
    public extern static IntPtr Canvas(string action);

    [DllImport(module)]
    public extern static IntPtr Dialog(IntPtr child);

    [DllImport(module)]
    public extern static IntPtr User();

    [DllImport(module)]
    public extern static IntPtr Label(string title);

    [DllImport(module)]
    public extern static IntPtr List(string action);

    [DllImport(module)]
    public extern static IntPtr Text(string action);

    [DllImport(module)]
    public extern static IntPtr MultiLine(string action);

    [DllImport(module)]
    public extern static IntPtr Toggle(string title, string action);

    [DllImport(module)]
    public extern static IntPtr Timer();

    [DllImport(module)]
    public extern static IntPtr ProgressBar();

    [DllImport(module)]
    public extern static IntPtr Val(string type);

    [DllImport(module)]
    public extern static IntPtr Tabsv(params IntPtr[] children);

    [DllImport(module)]
    public extern static IntPtr Tree();

    [DllImport(module)]
    public extern static IntPtr Spin();

    [DllImport(module)]
    public extern static IntPtr Spinbox(IntPtr child);


    #region TEXT_UTILITIES

    [DllImport(module)]
    public extern static void TextConvertLinColToPos(IntPtr ih, int lin, int col, out int pos);

    [DllImport(module)]
    public extern static void TextConvertPosToLinCol(IntPtr ih, int pos, out int lin, out int col);

    [DllImport(module)]
    public extern static int ConvertXYToPos(IntPtr ih, int x, int y); /* works also for list and tree */



    #endregion

    #region TREE_FUNCTIONS
    [DllImport(module)]
    public extern static int TreeSetUserId(IntPtr ih, int id, IntPtr userid);

    [DllImport(module)]
    public extern static IntPtr TreeGetUserId(IntPtr ih, int id);

    [DllImport(module)]
    public extern static int TreeGetId(IntPtr ih, IntPtr userid);

    [DllImport(module)]
    public extern static void TreeStoreAttribute(IntPtr ih, string name, int id, string value);

    [DllImport(module, EntryPoint = "TreeGetAttribute")]
    internal extern static IntPtr TreeGetAttributePtr(IntPtr ih, string name, int id);
    public static string TreeGetAttribute(IntPtr ih, string name, int id)
    {
      return PtrToString(TreeGetAttributePtr(ih, name, id));
    }

    [DllImport(module)]
    public extern static int TreeGetInt(IntPtr ih, string name, int id);

    [DllImport(module)]
    public static extern float TreeGetFloat(IntPtr ih, string name, int id);



    #endregion

    #region GL_FUNCTIONS

    [DllImport(module)]
    public extern static void GLCanvasOpen();

    [DllImport(module)]
    public extern static IntPtr GLCanvas(string action);

    [DllImport(module)]
    public extern static void GLMakeCurrent(IntPtr ih);

    [DllImport(module)]
    public extern static int GLIsCurrent(IntPtr ih);

    [DllImport(module)]
    public extern static void GLSwapBuffers();

    [DllImport(module)]
    public extern static void GLPalette(IntPtr ih, int index, float r, float g, float b);

    #endregion

    #region IM_LOADER_LINK
    [DllImport(module)]
    public extern static IntPtr LoadImage(string filename);

    [DllImport(module, EntryPoint = "LoadImage")]
    public extern static IntPtr LoadImageFromMemory(IntPtr filename);
    #endregion

    #region UTIL_FUNCTIONS
    private static string PtrToString(IntPtr str)
    {
      if (str == IntPtr.Zero)
        return null;
      return Marshal.PtrToStringAnsi(str);
    }

    #endregion


  }
}
